﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Experiment2
{
    public partial class Form1 : Form
    {
        //并发信号量设置可并行运行的线程数量
        public Semaphore put = new Semaphore(2, 2);//盘子上有两个空位，初始剩余2个空位，最多两个空位
        public Semaphore m = new Semaphore(1, 1);//儿子、女儿一次只能一个人拿水果
        public Semaphore n = new Semaphore(1, 1);//爸爸、妈妈一次只能一个人放水果
        public Semaphore appleput = new Semaphore(0, 2);//最多2个苹果,初始0
        public Semaphore orangeput = new Semaphore(0, 2);//最多2个橘子,初始0

        //爸爸进程thread1
        private void Threadfather1()
        {
            while (true)
            {
                textBox1.Text = "爸爸放苹果";
                Console.WriteLine("爸爸放苹果");
                put.WaitOne();
                m.WaitOne();//资源有空闲，爸爸可进进程，剩余信号量-1
                PMoveF();
                m.Release();//释放资源，剩余信号量+1
                Thread.Sleep(400);//线程休眠
            }
        }

        //父亲动画
        private void PMoveF()
        {
            //盘子左空，可放苹果
            if (orangel.Visible == false && applel.Visible == false)
            {
                //无苹果，释放信号量（+1）
                appleput.Release();
                int n = 10, x = 180, y = 31;
                for (int i = 0; i <= n; i++)
                {
                    pBdad.Location = new Point(x, y);
                    x += 18;
                    y += 14;
                    Thread.Sleep(70);
                }
                //放好苹果，空手回
                applel.Visible = true;
                pBdad.Image = Properties.Resources.handN;
                for (int i = 0; i <= n; i++)
                {
                    pBdad.Location = new Point(x, y);
                    x -= 18;
                    y -= 14;
                    Thread.Sleep(70);
                }
                //最后还原手是有苹果的
                pBdad.Image = Properties.Resources.HandAppleN;
            }
            else if (oranger.Visible == false && appler.Visible == false)   //盘子右空,可放苹果
            {
                //无苹果，释放信号量（+1）
                appleput.Release();
                int n = 10, x = 180, y = 31;
                for (int i = 0; i <= n; i++)
                {
                    pBdad.Location = new Point(x, y);
                    x += 18;
                    y += 15;
                    Thread.Sleep(70);
                }
                //放好苹果，空手回
                appler.Visible = true;
                pBdad.Image = Properties.Resources.handN;
                for (int i = 0; i <= n; i++)
                {
                    pBdad.Location = new Point(x, y);
                    x -= 18;
                    y -= 15;
                    Thread.Sleep(70);
                }
                //最后还原手是有苹果的
                pBdad.Image = Properties.Resources.HandAppleN;
            }
            else 
            {
                appleput.Release();
                int n = 10, x = 180, y = 31;
                for (int i = 0; i <= n; i++)
                {
                    pBdad.Location = new Point(x, y);
                    x += 20;
                    y += 15;
                    Thread.Sleep(70);
                }
                pBdad.Image = Properties.Resources.HandAppleN;
                for (int i = 0; i <= n; i++)
                {
                    pBdad.Location = new Point(x, y);
                    x -= 20;
                    y -= 15;
                    Thread.Sleep(70);
                }
            }
        }


        //妈妈进程thread2
        private void Threadmother1()
        {
            while (true)
            {
                textBox2.Text = "妈妈放橘子";
                Console.WriteLine("妈妈放橘子");
                put.WaitOne();
                m.WaitOne();//资源有空闲，可进进程，剩余信号量-1
                PMoveM();
                m.Release();//释放资源，剩余信号量+1
                Thread.Sleep(400);//线程休眠
            }
        }

        //母亲动画
        private void PMoveM()
        {
            //盘子右空，可放橘子
            if (appler.Visible == false && oranger.Visible == false)
            {
                //无橘子，释放信号量
                orangeput.Release();
                int n = 10, a = 627, b = 31;
                for (int i = 0; i <= n; i++)
                {
                    pBmom.Location = new Point(a, b);
                    a -= 18;
                    b += 16;
                    Thread.Sleep(70);
                }
                //空手回
                pBmom.Image = Properties.Resources.handN;
                oranger.Visible = true;
                for (int i = 0; i <= n; i++)
                {
                    pBmom.Location = new Point(a, b);
                    a += 18;
                    b -= 16;
                    Thread.Sleep(70);
                }
                pBmom.Image = Properties.Resources.HandOrangeN;
            }
            else if (applel.Visible == false && orangel.Visible == false)   //盘子左空，可放橘子
            {
                orangeput.Release();
                int n = 10, a = 627, b = 31;
                for (int i = 0; i <= n; i++)
                {
                    pBmom.Location = new Point(a, b);
                    a -= 20;
                    b += 15;
                    Thread.Sleep(70);
                }
                pBmom.Image = Properties.Resources.handN;
                orangel.Visible = true;
                for (int i = 0; i <= n; i++)
                {
                    pBmom.Location = new Point(a, b);
                    a += 20;
                    b -= 15;
                    Thread.Sleep(70);
                }
                pBmom.Image = Properties.Resources.HandOrangeN;
            }
            else
            {
                orangeput.Release();
                int n = 10, a = 627, b = 31;
                for (int i = 0; i <= n; i++)
                {
                    pBmom.Location = new Point(a, b);
                    a -= 25;
                    b += 17;
                    Thread.Sleep(70);
                }
                pBmom.Image = Properties.Resources.HandOrangeN;
                for (int i = 0; i <= n; i++)
                {
                    pBmom.Location = new Point(a, b);
                    a += 25;
                    b -= 17;
                    Thread.Sleep(70);
                }
            }
        }

        //儿子进程thread3
        private void Threadson1()
        {
            while (true)
            {
                textBox2.Text = "女儿拿苹果";
                Console.WriteLine("女儿拿苹果");
                appleput.WaitOne();
                n.WaitOne();//资源有空闲，可进进程，剩余信号量-1
                PMoveS();
                n.Release();//释放资源，剩余信号量+1
                Thread.Sleep(400);//线程休眠
            }
        }
    
        //儿子动画
        private void PMoveS()
        {
            //左边有苹果，可拿
            if (applel.Visible == true)
            {
                put.Release();
                int a = 180, b = 375;
                for (int i = 0; i <= 10; i++)
                {
                    pBson.Location = new Point(a, b);
                    a += 22;
                    b -= 20;
                    Thread.Sleep(70);
                }
                //儿子左苹果拿到，左苹果图片不可见
                applel.Visible = false;
                //苹果手拿回苹果
                pBson.Image = Properties.Resources.HandAppleN;
                for (int i = 0; i <= 10; i++)
                {
                    pBson.Location = new Point(a, b);
                    a -= 22;
                    b += 20;
                    Thread.Sleep(70);
                }
                //恢复默认手
                pBson.Image = Properties.Resources.handN;
            }
            else if (appler.Visible == true)
            {
                put.Release();
                int n = 10, a = 180, b = 375;
                for (int i = 0; i <= n; i++)
                {
                    pBson.Location = new Point(a, b);
                    a += 22;
                    b -= 20;
                    Thread.Sleep(70);
                }
                //儿子右苹果拿到，右苹果图片不可见
                appler.Visible = false;
                //苹果手拿回苹果
                pBson.Image = Properties.Resources.HandAppleN;
                for (int i = 0; i <= n; i++)
                {
                    pBson.Location = new Point(a, b);
                    a -= 22;
                    b += 20;
                    Thread.Sleep(70);
                }
                //恢复默认手
                pBson.Image = Properties.Resources.handN;
            }
            else
            {
                put.Release();
                int n = 10, a = 180, b = 375;
                for (int i = 0; i <= n; i++)
                {
                    pBson.Location = new Point(a, b);
                    a += 17;
                    b -= 14;
                    Thread.Sleep(70);
                }
                pBson.Image = Properties.Resources.handN;
                for (int i = 0; i <= n; i++)
                {
                    pBson.Location = new Point(a, b);
                    a -= 17;
                    b += 14;
                    Thread.Sleep(70);
                }
                pBson.Image = Properties.Resources.handN;
            }
        }

        //女儿进程thread4
        private void Threaddaughter1()
        {
            while (true)
            {
                textBox1.Text = "儿子拿橘子";
                Console.WriteLine("儿子拿橘子");
                orangeput.WaitOne();
                n.WaitOne();//资源有空闲，可进进程，剩余信号量-1
                PMoveD();
                n.Release();//释放资源，剩余信号量+1
                Thread.Sleep(400);//线程休眠
            }
        }

        //女儿动画
        private void PMoveD()
        {
            //右边有橘子可拿
            if (oranger.Visible == true)
            {
                put.Release();
                int n = 10, x = 622, y = 375;
                for (int i = 0; i <= n; i++)
                {
                    pBdau.Location = new Point(x, y);
                    x -= 15;
                    y -= 12;
                    Thread.Sleep(70);
                }
                //右边橘子消失
                oranger.Visible = false;
                pBdau.Image = Properties.Resources.HandOrangeN;
                for (int i = 0; i <= n; i++)
                {
                    pBdau.Location = new Point(x, y);
                    x += 15;
                    y += 12;
                    Thread.Sleep(100);
                }
                pBdau.Image = Properties.Resources.handN;
            }
            else if(orangel.Visible == true)
            {
                put.Release();
                int n = 10, x = 622, y = 375;
                for (int i = 0; i <= n; i++)
                {
                    pBdau.Location = new Point(x, y);
                    x -= 22;
                    y -= 15;
                    Thread.Sleep(70);
                }
                orangel.Visible = false;
                pBdau.Image = Properties.Resources.HandOrangeN;
                for (int i = 0; i <= n; i++)
                {
                    pBdau.Location = new Point(x, y);
                    x += 22;
                    y += 15;
                    Thread.Sleep(70);
                }
                pBdau.Image = Properties.Resources.handN;
            }
            else
            {
                put.Release();
                int n = 10, x = 622, y = 375;
                for (int i = 0; i <= n; i++)
                {
                    pBdau.Location = new Point(x, y);
                    x -= 20;
                    y -= 15;
                    Thread.Sleep(70);
                }
                pBdau.Image = Properties.Resources.handN;
                for (int i = 0; i <= n; i++)
                {
                    pBdau.Location = new Point(x, y);
                    x += 20;
                    y += 15;
                    Thread.Sleep(70);
                }
                pBdau.Image = Properties.Resources.handN;
            }
        }

        public Form1()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;
        }

        //加载
        private void Form1_Load(object sender, EventArgs e)
        {
            //盘子上的水果不可见
            applel.Visible = false; appler.Visible = false;
            orangel.Visible = false; oranger.Visible = false;

            //4个进程开始同时运行
            Thread thread1 = new Thread(new ThreadStart(Threadfather1));
            Thread thread2 = new Thread(new ThreadStart(Threadmother1));
            Thread thread3 = new Thread(new ThreadStart(Threadson1));
            Thread thread4 = new Thread(new ThreadStart(Threaddaughter1));
            thread1.Start();
            thread2.Start();
            thread3.Start();
            thread4.Start();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Environment.Exit(0);
        }

    }
}